package multi_thread.basic;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Description:
 * 学习地址：通过实现 Runnable接口 创建接口的实现类 RunnableImpl，根据 runnableImpl 实例创建线程实例。
 *
 * @author Cheng Jun
 * @version 1.0
 * @date 2019/10/29 9:35
 */
public class RunnableExample {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        Thread thread1 = new Thread(myRunnable);
        Thread thread2 = new Thread(myRunnable);

        // "启动3个线程(它们共用一个Runnable对象)，这3个线程一共卖10张票！"，这句话是错误的。
        // 多次运行该程序会出现这种情况。原因也很简单：当两个线程以上在 ticket 为1时，进入if 的 判断语句结果都为true，就会都执行卖票的语句。这里ticket应该是原子类型才对。
        // 如果在 MyRunnable.run()方法加上 synchronized 修饰的话，就会只有一个线程执行卖票程序，synchronized 获取的是当前对象的同步锁。
        thread.start();
        thread1.start();
        thread2.start();

        // ModifiedMyThread modifiedMyThread = new ModifiedMyThread();
        // Thread thread3 = new Thread(modifiedMyThread);
        // Thread thread4 = new Thread(modifiedMyThread);
        // Thread thread5 = new Thread(modifiedMyThread);
        //
        // thread3.start();
        // thread4.start();
        // thread5.start();

    }

    /**
     * 实现 Runnable 接口
     */
    static class MyRunnable implements Runnable {
        private int ticket = 10;

        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                if (this.ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + " 卖票：ticket" + this.ticket--);
                }
            }
        }
    }

    static class ModifiedMyThread implements Runnable {
        private AtomicInteger ticket = new AtomicInteger(10);

        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                if (ticket.get() > 0) {
                    System.out.println(Thread.currentThread().getName() + " 卖票：ticket" + ticket.getAndDecrement());
                }
            }
        }
    }
}


